package com.example.walkera.firstexoplayerdemo;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.text.TextRenderer;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;

import java.util.List;


/**
 * Created by kaifa@lihaiping on 2016/11/23.
 * 创建一个AVPlayerView，类似于SimpleExoPlayerView,但这里controll我们自己写，使用AVPlayerController来做控制条
 * 显示视频view
 */
public final class AVPlayerView extends FrameLayout{
    //定义内部变量
    private final String TAG="AVPlayerView";

    private SimpleExoPlayer mediaAVPlayer;
    private AVPlayerSimpleControllerView mediaAVPlayerController;
    private boolean bUseController=true;
    private int controllerShowTimeOutMs;

    private AspectRatioFrameLayout mediaAVPlayerLayout;
    private ComponentListener mediaAVPlayerCompListener;
    private View mediaVideoView;

    public AVPlayerView(Context context){
        this(context,null);
    }

    public AVPlayerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public AVPlayerView(Context context,AttributeSet attrs, int defStyleAttr){
        this(context,attrs,defStyleAttr,true,true);
    }

    public AVPlayerView(Context context, AttributeSet attrs, int defStyleAttr,boolean isUseAVPlayerControllerView, boolean isUseTextureView){
        super(context,attrs,defStyleAttr);
        //是否使用AVPlayerController
        bUseController=isUseAVPlayerControllerView;
        controllerShowTimeOutMs=AVPlayerSimpleControllerView.DEFAULT_SHOW_TIMEOUT_MS;
        //为此类加载一个布局文件
        LayoutInflater.from(context).inflate(R.layout.avplayer_view,this);

        int resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT;

        mediaAVPlayerCompListener=new ComponentListener();
        mediaAVPlayerLayout=(AspectRatioFrameLayout)findViewById(R.id.avplayer_video_frame);
        mediaAVPlayerLayout.setResizeMode(resizeMode);

        //获取到控制面板
        mediaAVPlayerController=(AVPlayerSimpleControllerView)findViewById(R.id.avplayer_simple_controller_panel);
        mediaAVPlayerController.hide();

        //创建一个view用于视频渲染
        View view=isUseTextureView?new TextureView(context):new SurfaceView(context);
        ViewGroup.LayoutParams params=new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        //为这个view设置一个布局参数
        view.setLayoutParams(params);

        mediaVideoView=view;
        mediaAVPlayerLayout.addView(mediaVideoView,0);
        Log.d(TAG, "AVPlayerView: successful");
    }

    public SimpleExoPlayer getMediaAVPlayer(){return mediaAVPlayer;}

    public void setMediaAVPlayer(SimpleExoPlayer player){
        if (this.mediaAVPlayer==player) {
            return;
        }
        if (this.mediaAVPlayer!=null){
            //this.mediaAVPlayer.setTextOutput(null);
            this.mediaAVPlayer.setVideoListener(null);
            this.mediaAVPlayer.removeListener(mediaAVPlayerCompListener);
            this.mediaAVPlayer.setVideoSurface(null);
        }
        this.mediaAVPlayer=player;
        //如果使用控制面板，这里设置controller的player用于controller内部进行相关调用
        if (bUseController){
            mediaAVPlayerController.setPlayer(player);
        }

        if (player!=null){
            if (mediaVideoView instanceof TextureView) {
                player.setVideoTextureView((TextureView) mediaVideoView);
            } else if (mediaVideoView instanceof SurfaceView) {
                player.setVideoSurfaceView((SurfaceView) mediaVideoView);
            }
            player.setVideoListener(mediaAVPlayerCompListener);
            player.addListener(mediaAVPlayerCompListener);
            //player.setTextOutput(mediaAVPlayerCompListener);
            maybeShowController(false);
        }
        else{
            mediaAVPlayerController.hide();
        }
    }

    /**
     * Returns whether the playback controls are enabled.
     */
    public boolean getUseController() {
        return bUseController;
    }

    /**
     * Sets whether playback controls are enabled. If set to {@code false} the playback controls are
     * never visible and are disconnected from the player.
     *
     * @param useController Whether playback controls should be enabled.
     */
    public void setUseController(boolean useController) {
        if (this.bUseController == useController) {
            return;
        }
        this.bUseController = useController;
        if (useController) {
            mediaAVPlayerController.setPlayer(mediaAVPlayer);
        } else {
            mediaAVPlayerController.hide();
            mediaAVPlayerController.setPlayer(null);
        }
    }

    /*add by kaifa@lihaiping on 20161125
    *添加设置这种控制面板显示时间和获取显示时间接口
    * */
    public int getControllerShowTimeOutMs(){return controllerShowTimeOutMs;}

    public void setControllerShowTimeOutMs(int showTimeOutMs){
        controllerShowTimeOutMs=showTimeOutMs;
    }

    /**
     * Set the {@link AVPlayerSimpleControllerView.VisibilityListener}.
     *
     * @param listener The listener to be notified about visibility changes.
     */
    public void setControllerVisibilityListener(AVPlayerSimpleControllerView.VisibilityListener listener) {
        mediaAVPlayerController.setVisibilityListener(listener);
    }

    /**
     * Get the view onto which video is rendered. This is either a {@link SurfaceView} (default)
     * or a {@link TextureView} if the {@code use_texture_view} view attribute has been set to true.
     *
     * @return either a {@link SurfaceView} or a {@link TextureView}.
     */
    public View getVideoSurfaceView() {
        return mediaVideoView;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (!bUseController || mediaAVPlayer == null || ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
            return false;
        }
        if (mediaAVPlayerController.isVisible()) {
            mediaAVPlayerController.hide();
        } else {
            maybeShowController(true);
        }
        return true;
    }

    @Override
    public boolean onTrackballEvent(MotionEvent ev) {
        if (!bUseController || mediaAVPlayerController == null) {
            return false;
        }
        maybeShowController(true);
        return true;
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        return bUseController ? mediaAVPlayerController.dispatchKeyEvent(event) : super.dispatchKeyEvent(event);
    }

    private void maybeShowController(boolean isForced) {
        if (!bUseController || mediaAVPlayer == null) {
            return;
        }
        int playbackState = mediaAVPlayer.getPlaybackState();
        boolean showIndefinitely = playbackState == ExoPlayer.STATE_IDLE
                || playbackState == ExoPlayer.STATE_ENDED || !mediaAVPlayer.getPlayWhenReady();
        boolean wasShowingIndefinitely = mediaAVPlayerController.isVisible() && mediaAVPlayerController.getShowTimeoutMs() <= 0;
        mediaAVPlayerController.setShowTimeoutMs(showIndefinitely ? 0 : controllerShowTimeOutMs);
        if (isForced || showIndefinitely || wasShowingIndefinitely) {
            mediaAVPlayerController.show();
        }
    }

    //////////////////////////////////////
    private final class ComponentListener implements SimpleExoPlayer.VideoListener, ExoPlayer.EventListener {


        // SimpleExoPlayer.VideoListener implementation

        @Override
        public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees,
                                       float pixelWidthHeightRatio) {
            mediaAVPlayerLayout.setAspectRatio(height == 0 ? 1 : (width * pixelWidthHeightRatio) / height);
        }

        @Override
        public void onRenderedFirstFrame() {
            // Do nothing.
        }

        @Override
        public void onVideoTracksDisabled() {
            // Do nothing.
        }

        // ExoPlayer.EventListener implementation

        @Override
        public void onLoadingChanged(boolean isLoading) {
            // Do nothing.
        }

        @Override
        public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
            maybeShowController(false);
        }

        @Override
        public void onPlayerError(ExoPlaybackException e) {
            // Do nothing.
        }

        @Override
        public void onPositionDiscontinuity() {
            // Do nothing.
        }

        @Override
        public void onTimelineChanged(Timeline timeline, Object manifest) {
            // Do nothing.
        }

    }
}
